import React, { Fragment } from 'react';
import { Table, Alert, BackTop, Pagination, Affix, notification, Slider, Button, Icon } from 'antd';
import { Resizable } from 'react-resizable';
import styles from './style.less';
import './index.css';
import { AxResizable } from '@/components/AxBase/AxResizable/index';
import { axconst } from '@/shared/axconst';
import { axhelper } from '@/shared/axhelper';
import ReactDOM from 'react-dom';

/**
 * 自定义Table组件
 * @param data 列表数据（包含了分页数据）
 * @param columns 列
 * @param loading 加载组件
 * @param checkboxModel 是否展示复选框（默认展示）
 * @param checkboxType 复选框类型checkbox - radio（默认checkbox）
 * @param checkboxFixed 是否固定复选框（默认固定）
 * @param showPagination 是否展示、展示类型（默认true  类型：'mini'）
 * @param scroll 设置滚动条
 * @param showSlider 是否展示顶部滑动条（默认true）
 * @param resizable 能否伸缩列（默认false）
 * @param totalMessage 统计信息（默认null）
 * @param flex 横向24栅格布局（采用此布局后，表格将会固定高度）
 * @param selectedRows 选中的行数据（用于父组件操作）
 * @param scrollY Table滚动条高度
 * @param affixPage 是否浮动分页控件（默认true）
 * @param selectOnClick 是否点击选中（默认true）
 * @param selectFirstRecord 自动选中第一行（默认false）
 * @param expandAll 展开全部树节点（默认false）
 * @param addemptycolumn 增加空白列（默认false）
 * @param onRef 用于父组件引用该组件
 * @param onSelectRow 选中行处理函数
 * @param onChange Table分页、排序、筛选事件的响应函数
 * @param onDoubleClick 双击行处理函数
 * @param onClick 单击击行处理函数
 */
class AxTable extends React.Component {
  components = {
    header: {
      cell: AxResizable,
    },
  };

  constructor(props) {
    super(props);
    this.state = {
      selectedRowKeys: [],
      selectedRows: props.selectedRows || []
    };
    // this.forScrollRef = element => {
    //   if (element && element.parentNode && element.parentNode.previousSibling) {
    //     const t = element.parentNode.previousSibling;
    //     // t.addEventListener("mousedown", this.onMouseDown);
    //     // t.addEventListener("mouseup", this.onMouseUp);
    //   }
    //   if (element && element.parentNode && element.parentNode.previousSibling) {
    //     // this.axScrollRef = element.parentNode.previousSibling;
    //     const t = document.getElementsByClassName('ant-table-body');
    //     const modal = document.getElementsByClassName('ant-modal-content');
    //     /** Table表格不在Modal中 */
    //     if (modal.length === 0 && t && t.length > 0) {
    //       this.axScrollRef = t[0];
    //       // this.axScrollRef.addEventListener('scroll', e => {
    //       //   this.setState({ axScrollLeft: e.target.scrollLeft });
    //       // });
    //     }
    //   }
    // };
  }

  componentDidMount() {
    const { onRef, data, selectFirstRecord = false, columns = [] } = this.props;
    if (onRef) {
      onRef(this);
    }
    if (selectFirstRecord && data && data.list && data.list.length > 0) {
      this.handleSelectRow({ record: data.list[0] });
    }
    this.setState({
      columns: columns.map(i => ({
        sorter: false,
        ellipsis: true,
        ...i,
      })),
    });

    /** 获取Table Body的ref */
    const tableCon = ReactDOM.findDOMNode(this); // 通过ref属性找到该table
    const modal = document.getElementsByClassName('ant-modal-content');
    /** Table表格不在Modal中 */
    if (modal.length === 0) {
      this.axScrollRef = tableCon.querySelector('.ant-table-body'); //获取table
    }
  }

  componentWillReceiveProps(newProps) {
    if (newProps.data !== this.props.data) {
      this.handleVerify();
      const { selectFirstRecord = false } = this.props;
      const { selectedRowKeys } = this.state;
      const { data } = newProps;
      if (
        selectedRowKeys.length === 0 &&
        selectFirstRecord &&
        data &&
        data.list &&
        data.list.length > 0
      ) {
        this.handleSelectRow({ record: data.list[0] });
      }
      // else {
      //   this.handleSelectRow({ record: {} });
      // }
    }
    if (newProps.columns !== this.props.columns) {
      this.setState({
        columns: newProps.columns.map(i => ({
          sorter: false,
          ellipsis: true,
          ...i,
        })),
      });
    }
  }

  /** 验证数据格式 */
  handleVerify = () => {
    const { list = [] } = this.props.data || {};
    if (Array.isArray(list) === false) {
      notification.error({
        message: '列表数据格式不正确',
      });
    }
  };

  /** 点击行选中处理函数 */
  handleSelectRow = ({ record }) => {
    let selectedRowKeys = [...this.state.selectedRowKeys];
    const { selectedRows: selectedRowsFromState } = this.state;
    let { onSelectRow, selectedRows = selectedRowsFromState, getCheckboxProps, checkboxType } = this.props;

    if (getCheckboxProps) {
      const { disabled } = getCheckboxProps(record);
      /** 如果复选框无效，直接返回 */
      if (disabled === true) {
        return;
      }
    }

    if (selectedRowKeys.indexOf(record.id) >= 0) {
      selectedRowKeys.splice(selectedRowKeys.indexOf(record.id), 1);
      selectedRows.splice(selectedRows.indexOf(record), 1);
    } else {
      selectedRowKeys.push(record.id);
      selectedRows.push(record);
    }
    if (checkboxType === 'radio') {
      selectedRowKeys = [];
      selectedRows = [];
      record.id && selectedRowKeys.push(record.id);
      record && selectedRows.push(record);
    }
    if (onSelectRow) {
      onSelectRow(selectedRows, record);
    }
    this.setState({ selectedRowKeys, selectedRows });
  };

  /** 点击checkbox选中处理函数 */
  handleRowSelectChange = (selectedRowKeys, selectedRows) => {
    const { onSelectRow } = this.props;

    if (onSelectRow) {
      onSelectRow(selectedRows);
    }

    this.setState({
      selectedRowKeys,
      selectedRows,
    });
  };

  /** 用户手动选择/取消选择某行的回调 */
  handleRowSelect = (record, selected, selectedRows, nativeEvent) => {
    const { onSelectRow } = this.props;

    if (onSelectRow) {
      onSelectRow(selectedRows, record);
    }
  };

  /** 清空选中的行 */
  cleanSelectedKeys = () => {
    if (this.handleRowSelectChange) {
      this.handleRowSelectChange([], []);
    }
  };

  /** 构造统计的列 */
  initTotalList = columns => {
    const totalList = [];

    if (!columns) {
      return [];
    }
    columns.forEach(column => {
      if (column.needTotal) {
        totalList.push({ ...column, total: 0 });
      }
    });
    return totalList;
  };

  /** 生成统计数据 */
  getTotalList = (columns, list) => {
    let needTotalList = this.initTotalList(columns);

    if (list && Array.isArray(list)) {
      needTotalList = needTotalList.map(item => ({
        ...item,
        total: list.reduce((sum, val) => {
          if (!isNaN(parseFloat(val[item.dataIndex || 0]))) {
            sum += parseFloat(val[item.dataIndex || 0]);
          }
          return sum;
        }, 0),
      }));
    }
    return needTotalList;
  };

  /** 改变宽度 */
  handleResize = index => (e, { size }) => {
    if (e) e.preventDefault();
    this.setState(({ columns }) => {
      const nextColumns = [...columns];
      nextColumns[index] = {
        ...nextColumns[index],
        width: size.width,
      };
      return { columns: nextColumns };
    });
  };

  /** 滑动条 */
  handleSliderChange = val => {
    if (this.axScrollRef && this.axScrollRef.scroll) this.axScrollRef.scroll(val, 0);
  };

  render() {
    const { selectedRowKeys, axScrollLeft } = this.state;
    const {
      data,
      affixPage = true,
      checkboxModel = true,
      checkboxType = 'checkbox',
      checkboxFixed = true,
      scroll = true,
      showPagination = true,
      onDoubleClick,
      onClick,
      onChange,
      onGetFirstData = false,
      resizable = false,
      showSlider = true,
      totalMessage = null,
      getCheckboxProps = () => { },
      flex,
      scrollY,
      selectOnClick = true,
      components = {},
      columns,
      expandAll = false,
      expandedRowKeys = [],
      addemptycolumn = false,
      showTopSlider: showTopSliderFromProps = true,
      ...rest
    } = this.props;

    let {
      needRowClass = true,
    } = this.props;

    const { list = [], pagination = false } = data || {};
    let { columns: axcolumns = [] } = this.state;

    /** 验证数据格式 */
    if (Array.isArray(list) === false) {
      return null;
    }
    //无数据时显示
    let locale = { emptyText: <div style={{ padding: '30px 0', color: '#bbb' }}><p><Icon type="dropbox" style={{ fontSize: '40px', color: '#ccc' }} /></p>未搜索到符合条件的数据</div> };
    data && !data.success && !onGetFirstData && (locale = { emptyText: '暂未获取数据,请点击搜索或刷新按钮' })
    data && !data.success && onGetFirstData && (locale = {
      emptyText:
        <div style={{ padding: '30px 0', color: '#000' }}>
          <p><Icon type="file-search" style={{ fontSize: '40px', color: '#bbb' }} /></p>
        请输入相关查询条件进行查询，如无搜索条件可<Button type="link" size="small" onClick={() => onGetFirstData()}>立即搜索</Button></div>
    })
    /** 分页 */
    const paginationProps =
      pagination && showPagination
        ? {
          showSizeChanger: true,
          showQuickJumper: true,
          // position: 'top',
          style: {
            marginTop: '5px',
            height: 32,
            // marginBottom: '16px',
            float: 'right',
            backgroundColor: 'white',
          },
          showTotal: (total, range) => `显示 ${range[0]}-${range[1]} 条，共 ${total} 条`,
          onChange: (current, pageSize) => onChange({ current, pageSize }, null, null),
          onShowSizeChange: (current, pageSize) => onChange({ current, pageSize }, null, null),
          ...pagination,
        }
        : false;

    /** 迷你分页 */
    const smallPaginationProps =
      pagination && showPagination
        ? {
          size: 'small',
          style: {
            marginTop: '5px',
            height: 32,
            // marginBottom: '16px',
            float: 'right',
            backgroundColor: 'white',
          },
          onChange: (current, pageSize) => onChange({ current, pageSize }, null, null),
          ...pagination,
        }
        : false;

    const page = showPagination === 'mini' ? smallPaginationProps : paginationProps;

    /** 复选框 */
    const rowSelection =
      checkboxModel === true
        ? {
          selectedRowKeys,
          onChange: this.handleRowSelectChange,
          onSelect: this.handleRowSelect,
          /** 选择框的默认属性配置 */
          getCheckboxProps: getCheckboxProps,
          fixed: checkboxFixed,
          type: checkboxType,
          columnWidth: axconst.width.checkbox,
        }
        : null;

    /** 滚动条 */
    let scrollProps = scroll
      ? scroll === true
        ? { x: 'max-content' }
        : { x: 'max-content', ...scroll }
      : '-';

    /** 添加空白列 */
    if (addemptycolumn && axcolumns && axcolumns.findIndex(f => f.dataIndex === 'ax_empty_data_index') === -1) {
      axcolumns.push(
        {
          title: '',
          dataIndex: 'ax_empty_data_index',
          sorter: false,
          ellipsis: true,
        });
    }

    let axcomponents = { ...components };
    /** 伸缩列 */
    if (resizable && axcolumns) {
      axcomponents = { ...axcomponents, ...this.components };
      const len = axcolumns.length - 1;
      axcolumns = axcolumns.map((col, idx) => ({
        onHeaderCell: column => ({
          width: column.width,
          last: len === idx,
          onResize: this.handleResize(idx),
        }),
        ...col,
      }));
    }

    /** 统计数据 */
    // const needTotalList = this.getTotalList(axcolumns, list);

    /** 顶部滑动条 */
    let scrollWidth = 0;
    let scrollHeight = 0;
    /** 是否展示顶部滑动条 */
    let showTopSlider = false;
    if (showTopSliderFromProps) {
      if (this.axScrollRef) {
        scrollWidth = this.axScrollRef.scrollWidth - this.axScrollRef.clientWidth;
        scrollHeight = document.body.scrollHeight - document.body.clientHeight;
      }
      if (showSlider === true && scrollProps !== '-' && scrollWidth > 0 && scrollHeight > 0) {
        showTopSlider = true;
      }
    }

    let style = {};
    const tableTitleHeight = 38;
    if (flex) {
      // const top = 161;
      const titleHeight = 56;
      const buttonHeight = 24 + 34 + 11;
      const pageHeight = 5 + 32 + 5;
      const scrollY =
        ((document.body.clientHeight - 88) * flex) / 24 -
        titleHeight -
        buttonHeight -
        tableTitleHeight -
        pageHeight;
      scrollProps = {
        x: 'max-content',
        y: scrollY,
      };
    }
    if (scrollY) {
      scrollProps = {
        x: 'max-content',
        y: scrollY,
      };
    }
    /** 当设置了滚动条的高度时，需要设置整个Table的高度 */
    if (scrollProps && scrollProps.y) {
      style = {
        height: scrollProps.y + tableTitleHeight,
      };
    }

    let axExpandedRowKeys = [];
    if (expandAll && expandedRowKeys.length === 0) {
      function getId(d) {
        let l = [];
        d.map(i => {
          l.push(i.id);
          if (i.children) l.push(...getId(i.children));
        });
        return l;
      }
      axExpandedRowKeys = getId(list);
    } else {
      axExpandedRowKeys = expandedRowKeys;
    }

    /** 树形Table时，不加隔行变色 */
    if (needRowClass === true) {
      needRowClass = list.findIndex(f => f.children) === -1;
    }

    return (
      <div className={styles.standardTable}>
        {/* 顶部滑动条 */}
        {showTopSlider && (
          <Affix offsetTop={6 + axconst.header.height}>
            <Slider
              style={{
                marginTop: '0px',
                marginBottom: '0px',
                paddingTop: '0px',
                backgroundColor: 'white',
              }}
              tipFormatter={null}
              // value={axScrollLeft}
              max={scrollWidth}
              onChange={this.handleSliderChange}
            />
          </Affix>
        )}
        {/* 统计 */}
        {/* {needTotalList && needTotalList.length > 0 && (
          <div className={styles.axTotalAlert}>
            <Alert
              message={
                <>
                  共计 <a className="ax-total-alert">{list.length}</a> 项&nbsp;&nbsp;
                  {needTotalList.map((item, index) => (
                    <span key={item.dataIndex} className="ax-total-title">
                      {item.title}&nbsp;
                      <span className="ax-total-content">
                        {item.render ? item.render(item.total, item, index) : item.total}
                      </span>
                    </span>
                  ))}
                </>
              }
              type="info"
              showIcon
            />
          </div>
        )} */}
        {/* 自定义统计信息 */}
        {totalMessage && <div className={styles.tableAlert}>{totalMessage}</div>}
        <Table
          // bordered
          // size="small"
          rowKey={record => record.id}
          // 表格行是否可选择
          // 通过 rowSelection.selectedRowKeys 来控制选中项
          // 注释掉就没有选择框了
          rowSelection={rowSelection}
          dataSource={list}
          locale={locale}
          columns={axcolumns}
          pagination={false}
          scroll={scrollProps}
          components={axcomponents}
          style={style}
          defaultExpandAllRows={true}
          expandedRowKeys={axExpandedRowKeys}
          onChange={onChange}
          rowClassName={(record, idx) => {
            const { clickRowIndex } = this.state;
            let cls = (needRowClass && idx % 2 === 0) ? 'ax-table-row-background-color1' : ''
            if (clickRowIndex === idx) {
              cls = 'ax-table-row-background-color-select';
            }
            return cls;
          }}
          onRow={record => ({
            onDoubleClick: (e) => {
              if (onDoubleClick) {
                onDoubleClick(record, e);
              }
            },
            onClick: event => {
              if (selectOnClick === true) this.handleSelectRow({ record, event });
              onClick && onClick({ record, event })
            },
          })}
          // onRowClick={(record, index, event) => {
          //   if (selectOnClick === true) this.handleSelectRow({ record, event });
          // }}
          {...rest}
        />
        {page &&
          (affixPage ? (
            <Affix offsetBottom={37}>
              <Pagination pageSizeOptions={['10', '20', '30', '40']} {...page} />
            </Affix>
          ) : (
            <Pagination pageSizeOptions={['10', '20', '30', '40']} {...page} />
          ))}
        <BackTop visibilityHeight={100}>
          {/* <div className={styles.antBackTopInner}>UP</div> */}
        </BackTop>
        <div ref={this.forScrollRef}></div>
      </div>
    );
  }
}

export default AxTable;
